package com.holly.unit.deform.designer.core.validator;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.holly.unit.deform.api.exception.DeformException;
import com.holly.unit.deform.api.exception.enums.DeformExceptionEnum;
import com.holly.unit.deform.designer.core.parser.FormElementIterator;
import com.holly.unit.deform.designer.enums.AdvanceElementEnum;
import com.holly.unit.deform.designer.model.FormElement;
import com.holly.unit.deform.designer.model.Rule;
import com.holly.unit.deform.designer.util.DeFormUtil;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 类描述: FormMaking 表单校验
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/8/4 8:08
 */
public class FormMakingValidator {

    /**
     * 表单校验
     * @param formTemplate 表单模板json
     * @param formValue 表单填写数据
     * @return 表单校验结果
     */
    public FormValidator validator(String formTemplate , String formValue) {

        if (StrUtil.isBlank(formTemplate)) {
            throw new DeformException(DeformExceptionEnum.DEFORM_DESIGNER_TEMPLATE_NULL);
        }

        if (StrUtil.isBlank(formValue)) {
            throw new DeformException(DeformExceptionEnum.DEFORM_DESIGNER_VALUE_NULL);
        }
        JSONObject form = JSON.parseObject(formTemplate);
        JSONObject value = JSON.parseObject(formValue);
        return validator(form, value);
    }

    /**
     * 表单校验
     * @param formTemplate 表单模板json
     * @param formValue 表单填写数据
     * @return 表单校验结果
     */
    public FormValidator validator(JSONObject formTemplate,JSONObject formValue) {
        FormValidator formv = new FormValidator();
        formv.setResult(true);
        JSONArray list = formTemplate.getJSONArray("list");
        // 获得FormElement元素列表
        List<FormElement> elements = FormElementIterator.iterator(list);
        if (elements == null || elements.isEmpty()) return formv;
        // 字段校验
        List<FieldValidator> fieldValidaotrs = new LinkedList<>();
        for (FormElement element:elements) {
            FieldValidator fv = validateFields(element, formValue);
        }


        return formv;
    }

    private  FieldValidator  validateFields(FormElement element,JSONObject value){
        if (element == null) return null;
        FieldValidator fv  = new FieldValidator();

        // 判断是否有父，并且父是否隐藏
        if (element.getParentOp() != null) {
            // 如果父隐藏直接返回
            boolean parentVisible = DeFormUtil.recordVisible(element.getParentOp(),value);
            if (!parentVisible) {
                return null;
            }
        }
        // 判断是否隐藏
        boolean visible = DeFormUtil.recordVisible(element, value);
        if (!visible) return null;
        // 判断是否有规则校验
        if (element.getRules() == null || element.getRules().isEmpty()) return null;
        fv.setModel(element.getModel());
        fv.setFieldName(element.getName());
        // 校验规则
        Rule ruleValidaor = DeFormUtil.recordRuleValidator(element, value);
        fv.setResult(ruleValidaor == null);
        fv.setRule(ruleValidaor);
        if (ruleValidaor != null) {
            fv.setMessage(ruleValidaor.getMessage());
            fv.setType(element.getType());
        }

        // 子表单 或者子表单+
        String type = element.getType();
        if (type.equals(AdvanceElementEnum.TABLE.fieldName())) { // 表单
            // 取出数据
            JSONArray batchValue = value.getJSONArray(element.getModel());
            if (batchValue == null) {
                // 如果结果验证通过返回空
                if (fv.getResult() == true) return null;
                return fv;
            }
            // 验证子表单中每条数据
            List<BatchListValidator> batchVlidatorList = new LinkedList<>();
            List<FormElement> childElement = element.getChild();
            int batchSize = batchValue.size();
            for(int j = 0 ; j < batchSize ; j++) {
                List<FieldValidator> batchValidate = new ArrayList<>();
                BatchListValidator batchValidator = new BatchListValidator();
                JSONObject batchSubValue = batchValue.getJSONObject(j);
                for(FormElement fe : childElement) {
                    FieldValidator vali = validateFields(fe, batchSubValue);
                    if(vali != null) {
                        batchValidate.add(vali);
                    }

                }
                if(!batchValidate.isEmpty()) {
                    batchValidator.setIndex(j);
                    batchValidator.setResult(false);
                    batchValidator.setChild(batchValidate);
                    batchVlidatorList.add(batchValidator);
                }
            }

            if(!batchVlidatorList.isEmpty()) {
                // 验证不通过
                fv.setChild(batchVlidatorList);
                fv.setResult(false);
            }
        }
        // 如果验证通过并且没有子child 则返回null
        if((fv == null || fv.getResult() == true)  && (fv.getChild() == null || fv.getChild().isEmpty()) ) {
            return null ;
        }
        return fv;
    }
}
